---
type: tutorial
title: Создайте свой первый макет
description: |-
  Учебное пособие: Создайте свой первый блог на Astro —
  Рефакторинг общих элементов в повторно используемый макет страницы
i18nReady: true
---
import Box from '~/components/tutorial/Box.astro';
import Checklist from '~/components/Checklist.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';


<PreCheck>
  - Рефакторить общие элементы в макете страницы
  - Использовать элемент Astro `<slot />` для размещения содержимого страницы в макете
  - Передать значения, специфичные для страницы, как свойств в макет
</PreCheck>

У вас все еще есть некоторые компоненты Astro, которые неоднократно отображаются на каждой странице. Пришло время снова провести рефакторинг, чтобы создать общий макет страницы!

## Создание вашего первого компонента макета

<Steps>
1. Создайте новый файл в расположении `src/layouts/BaseLayout.astro`. (Сначала вам нужно создать новую папку `layouts`.)

2. Скопируйте **весь контент** из `index.astro` в ваш новый файл, `BaseLayout.astro`.

    ```astro title="src/layouts/BaseLayout.astro"
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Home Page";
    ---
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="viewport" content="width=device-width" />
        <meta name="generator" content={Astro.generator} />
        <title>{pageTitle}</title>
      </head>
      <body>
        <Header />
        <h1>{pageTitle}</h1>
        <Footer />
        <script>
          import "../scripts/menu.js";
        </script>
      </body>
    </html>
    ```
</Steps>

## Использование макета на странице

<Steps>
3. Замените код в файле `src/pages/index.astro` на следующий:

    ```astro title="src/pages/index.astro"
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    const pageTitle = "Home Page";
    ---
    <BaseLayout>
      <h2>My awesome blog subtitle</h2>
    </BaseLayout>
    ```

4. Снова проверьте предварительный просмотр в браузере, чтобы заметить, что изменилось (или, спойлер: _не изменилось_!).

5. Добавьте элемент `<slot />` в файл `src/layouts/BaseLayout.astro` прямо перед компонентом футера, затем проверьте предварительный просмотр в браузере вашей страницы «Главная» и заметьте, что _на этот раз_ действительно изменилось!

    ```astro title="src/layouts/BaseLayout.astro" ins={18}
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Home Page";
    ---
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
        <meta name="viewport" content="width=device-width" />
        <meta name="generator" content={Astro.generator} />
        <title>{pageTitle}</title>
      </head>
      <body>
        <Header />
        <h1>{pageTitle}</h1>
        <slot />
        <Footer />
        <script>
          import "../scripts/menu.js";
        </script>
      </body>
    </html>
    ```
</Steps>

Элемент `<slot />` позволяет вам внедрять (или «slotting in») **дочерний контент**, написанный между открывающими и закрывающими тегами `<Component></Component>`, в любой файл `Component.astro`.

## Передача значений, относящихся к странице, в качестве свойств

<Steps>
6. Передайте заголовок страницы в ваш компонент макета из `index.astro`, используя атрибут компонента:

    ```astro title="src/pages/index.astro" 'pageTitle={pageTitle}'
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    const pageTitle = "Home Page";
    ---
    <BaseLayout pageTitle={pageTitle}>
      <h2>My awesome blog subtitle</h2>
    </BaseLayout>
    ```

7. Измените скрипт вашего компонента макета `BaseLayout.astro`, чтобы он получал заголовок страницы через `Astro.props`, а не определял его как константу.

    ```astro title="src/layouts/BaseLayout.astro" del={5} ins={6}
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Home Page";
    const { pageTitle } = Astro.props;
    ---
    ```

8. Проверьте предварительный просмотр в браузере, чтобы убедиться, что заголовок вашей страницы не изменился. Его значение осталось прежним, но теперь он рендерится динамически. Теперь на каждой отдельной странице можно указывать свой собственный заголовок для макета.
</Steps>

<Box icon="puzzle-piece">

## Попробуйте сами — Используйте свой макет везде

Переделайте остальные страницы (`blog.astro` и `about.astro`) так, чтобы они использовали ваш новый компонент `<BaseLayout>` для отображения общих элементов страницы.

**Не забудьте:**

- Передайте заголовок страницы в виде свойств через атрибут компонента.

- Позвольте макету отвечать за рендеринг HTML любых общих элементов.

- Удалите из каждой страницы все, за что она больше не отвечает за рендеринг, потому что управляется макетом, включая:

  - элементы HTML
  - компоненты и их импорты
  - CSS правила в теге `<style>` (например, `<h1>` на вашей странице Главная)
  - теги `<script>`

</Box>



<Box icon="question-mark">

### Проверьте свои знания

1. Компонент Astro (`.astro` файл) может функционировать как:

    <MultipleChoice>
      <Option>страница</Option>
      <Option>компонент пользовательского интерфейса</Option>
      <Option>макет</Option>
      <Option>изображение</Option>
      <Option isCorrect>все вышеперечисленное, потому что компоненты Astro настолько функциональны! 🏗️</Option>
    </MultipleChoice>

2. Чтобы отображать заголовок страницы на странице, вы можете:

    <MultipleChoice>
      <Option>
        использовать стандартный элемент HTML на странице со статическим текстом (например: `<h1>Главная страница</h1>`)
      </Option>
      <Option>
        использовать стандартный элемент HTML на странице, ссылаясь на переменную, определенную в сценарии frontmatter вашего компонента (например `<h1>{pageTitle}</h1>`)
      </Option>
      <Option>
        использовать макет на странице, передавая заголовок как атрибут компонента (например. `<BaseLayout title="Главная" />` или `<BaseLayout title={pageTitle} />`)
      </Option>
      <Option isCorrect>
        все вышеперечисленное, потому что Astro позволяет использовать обычный HTML или усилить его с помощью сценариев и компонентов! 💪
      </Option>
    </MultipleChoice>

3. Информацию можно передавать из одного компонента в другой следующим образом:

    <MultipleChoice>
      <Option>
        импортировать компонент пользовательского интерфейса и рендерить его в шаблоне другого компонента
      </Option>
      <Option>
        передавать свойства в компонент, где они рендерятся через атрибут компонента
      </Option>
      <Option>
        отправлять HTML-контент, который должен рендериться внутри другого компонента, используя заполнитель `<slot />`
      </Option>
      <Option isCorrect>
        все вышеперечисленное, потому что Astro был создан для использования преимуществ компонентного дизайна! 🧩
      </Option>
    </MultipleChoice>

</Box>

<Box icon="check-list">

## Чек-лист

<Checklist>
- [ ] Я могу создать компонент макета Astro с помощью `<slot />`.
- [ ] Я могу передавать макету свойства, специфичные для страницы.
</Checklist>
</Box>

### Ресурсы

- [Компоненты макета Astro](/ru/basics/layouts/)

- [Astro `<slot />`](/ru/basics/astro-components/#слоты)